#include "statsxx/machine_learning/RBM.hpp"                  // this->v_to_h(), this->h_to_v()

// STL
#include <utility>                                           // std::pair<>, std::make_pair()

// jScience
#include "jScience/linalg.hpp"                               // Matrix<>, Vector<>, outer_product()


//
// NOTE: There is no sampling in this subroutine (deterministic).
//
inline std::pair<
                 Vector<double>,
                 Vector<double>
                 > machine_learning::RBM::reconstruct(
                                                      const Vector<double> &_v
                                                      ) const
{
    Vector<double> v;
    Vector<double> h;
    
    // ----- POSITIVE PHASE -----
    h = this->v_to_h(_v);
    
    // ----- NEGATIVE PHASE -----
    v = this->h_to_v(h);

    return std::make_pair(
                          v,
                          h
                          );
}


inline std::pair<
                 Matrix<double>,
                 Matrix<double>
                 > machine_learning::RBM::reconstruct(
                                                      const Matrix<double> &V
                                                      ) const
{
    Matrix<double> Vn(V.size(0),nv);
    Matrix<double> Hp(V.size(0),nh);
    
    for(auto i = 0; i < V.size(0); ++i)
    {
        Vector<double> vn;
        Vector<double> hp;
        std::tie(
                 vn,
                 hp
                 ) = this->reconstruct(
                                       V.row(i)
                                       );
        
        for(int j = 0; j < nv; ++j)
        {
            Vn(i,j) = vn(j);
        }
        
        for(int j = 0; j < nh; ++j)
        {
            Hp(i,j) = hp(j);
        }
    }
    
    return std::make_pair(
                          Vn,
                          Hp
                          );
}
